# -*- coding: utf-8 -*-

'''
Created on 21.07.2011

@author: Vlasov A. I. <root@proscript.ru>
'''
import datetime

from django import forms

from models import Category, Service, Document, Statement

from settings import OKNO

from util.widgets import *

class CategoryForm(forms.Form):
    
    id = forms.IntegerField(initial=0, widget=forms.HiddenInput, required=False)
    categories = forms.ModelMultipleChoiceField(queryset=Category.objects.all(), widget=CheckboxSelectMultipleGroups,
                                                 required=False, label=u'Категории')
    
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=forms.util.ErrorList, label_suffix=':',
                 empty_permitted=False):
        
        super(CategoryForm, self).__init__(data, files, auto_id, prefix,
                 initial, error_class, label_suffix,
                 empty_permitted)

    
    
class ServiceForm(forms.Form):
    
    id = forms.IntegerField(widget=forms.HiddenInput, required=False)
    services = forms.ModelMultipleChoiceField(queryset = Service.objects.none(), widget=CheckboxSelectMultipleGroups,
                                            required=False, label=u'Услуги')
    categories = forms.ModelMultipleChoiceField(queryset = Category.objects.none(), widget=forms.MultipleHiddenInput)
    
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=forms.util.ErrorList, label_suffix=':',
                 empty_permitted=False):
        
        super(ServiceForm, self).__init__(data, files, auto_id, prefix,
                 initial, error_class, label_suffix,
                 empty_permitted)
        
        categories = None
        if data:
            categories = data.getlist('categories')
        if initial:
            categories = initial['categories']
        
        if categories:
            self.fields[u'categories'].queryset = Category.objects.filter(id__in=categories)
            self.fields[u'services'].queryset = Service.objects.select_related().filter(categories__in=categories).distinct()
        # Где-то в любом случае должен быть список категорий. Иначе эта форма бессмысленна и проверку не пройдет

      
class DocumentForm(forms.Form):
    
    id = forms.IntegerField(widget=forms.HiddenInput, required=False)
    documents = forms.ModelMultipleChoiceField(queryset = Document.objects.none(), widget=CheckboxSelectMultipleGroups,
                                            required=False, label=u'Документы')
    services = forms.ModelMultipleChoiceField(queryset = Service.objects.none(), widget=forms.MultipleHiddenInput)
    categories = forms.ModelMultipleChoiceField(queryset = Category.objects.none(), widget=forms.MultipleHiddenInput)
    
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=forms.util.ErrorList, label_suffix=':',
                 empty_permitted=False):
        
        super(DocumentForm, self).__init__(data, files, auto_id, prefix,
                 initial, error_class, label_suffix,
                 empty_permitted)
        
        services = None
        if data:
            services = data.getlist('services')
            categories = data.getlist('categories')
        if initial:
            services = initial['services']
            categories = initial['categories']
        if services:
            self.fields[u'services'].queryset = Service.objects.filter(id__in=services)
            self.fields[u'categories'].queryset = Category.objects.filter(id__in=categories)
            self.fields[u'documents'].queryset = Document.objects.select_related().filter(
                                                                    services__in=services).filter(
                                                                    categories__in=categories).distinct()
        # Где-то в любом случае должен быть список категорий и услуг. Иначе эта форма бессмысленна и проверку не пройдет
                    
"""                   
class StatementForm(forms.ModelForm):
    
    class Meta:
        model = Statement
    
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=forms.util.ErrorList, label_suffix=':',
                 empty_permitted=False, instance=None):
        
        super(StatementForm, self).__init__(data, files, auto_id, prefix,
                 initial, error_class, label_suffix,
                 empty_permitted, instance)
        
        ### Устанавливаем атрибуты формы по умолчанию
        #### Регистрационный номер заявления
        #### Новое заявление: -1, при сохранении присваивается новый номер.
        #### Если идет редактирование, старый номер не меняется.

        if initial is None or not initial.has_key('number'):
            self.fields[u'number'].initial = -1
            self.fields[u'phone'].initial = OKNO['phone']
            ### Если настроен район по-умолчанию, выбираем его
            if OKNO.has_key('area'):
                self.fields[u'area'].initial = OKNO['area'] 
           
        self.fields[u'number'].widget = forms.HiddenInput()
        
        ### Паспорт
        self.fields[u'pasport'].widget = PasportInputHTML5()
        #self.fields[u'pasport_prod_date'].widget = DateFieldHTML5(format='%Y-%m-%d')
        
        #### Дата регистрации заявления
        self.fields[u'date'].widget = forms.HiddenInput()
        
        self.fields[u'phone'].widget = PhoneInputHTML5()
        
        #### Категории, услуги и документы
        self.fields[u'categories'].widget = forms.MultipleHiddenInput()
        self.fields[u'services'].widget = forms.MultipleHiddenInput()
        self.fields[u'documents'].widget = forms.MultipleHiddenInput()

    def set_new_instance_number(self):
        self.instance.number = self.__get_free_number()
        
    def clean_number(self):
        number = self.cleaned_data['number']
        
        if number == -1:
            return self.__get_free_number()
        return number
    '''
        Выбирает последнюю запись из БД (по идентификатору) за текущий год
        и увеличивает номер из записи на 1, возвращает полученное значение.
        Иначе нумерация начинается с начала (за текущий год не было еще ни одной записи)
    '''   
    def __get_free_number(self):
        number = 1
        try:
            
            st = Statement.objects.filter(date__gte=datetime.date(datetime.date.today().year, 1, 1)).order_by('-id').values('number')
            if st:
            #if datetime.date.today().year == st['date'].year:
                number = st[0]['number'] + 1
        except IndexError:
            pass
        except Exception:
            pass
        
        return number
    
    def clean_pasport(self):
        pasport = self.cleaned_data['pasport']
        
        pasport = re.sub(ur'[^\d]*', '', pasport, re.U)
        pasport = re.sub(ur'(\d{2})(\d{2})(\d{6})', ur'\1 \2 №\3', pasport, re.U)
        
        return pasport

    def clean_phone(self):
        phone = self.cleaned_data['phone']
        
        if ',' in phone:
            new_phone = ', '.join([self.__clean_phone(x.strip()) for x in phone.split(',')])
        else:
            new_phone = self.__clean_phone(phone)
        
        return new_phone
        
    def __clean_phone(self, value):
        if re.match(ur'\+\d \((\d{5}\) \d|\d{4}\) \d{2}|\d{3}\) \d{3})-\d{2}-\d{2}', value, re.U):
            return value
            
        value = re.sub(ur'[^\d]*', '', value, re.U)
        if len(value) == 5:
            value = re.sub(ur'(\d)(\d{2})(\d{2})', ur'+7 (85144) \1-\2-\3', value, re.U)
        else:
            value = re.sub(ur'[78]?(\d{5})(\d)(\d{2})(\d{2})', ur'+7 (\1) \2-\3-\4', value, re.U)
        
        return value
"""

class StatementForm(forms.ModelForm):
    
    class Meta:
        model = Statement
    
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=forms.util.ErrorList, label_suffix=':',
                 empty_permitted=False, instance=None):
        
        if initial:
            if not initial.get('phone', None) or instance:
                del initial['phone']
        
        super(StatementForm, self).__init__(data, files, auto_id, prefix,
                 initial, error_class, label_suffix,
                 empty_permitted, instance)
        
        ### Устанавливаем атрибуты формы по умолчанию
        #### Регистрационный номер заявления
        #### Новое заявление: -1, при сохранении присваивается новый номер.
        #### Если идет редактирование, старый номер не меняется.
        
        
        if initial is None or not initial.has_key('number'):
            self.fields[u'number'].initial = -1
            
            ### Если настроен район по-умолчанию, выбираем его
            if OKNO.has_key('area'):
                self.fields[u'area'].initial = OKNO['area']

        
            self.fields[u'phone'].initial = OKNO['phone']
            
        #if instance:
        #    self.fields[u'number'].widget = forms.HiddenInput()
        #else:
        self.fields[u'number'].widget = forms.TextInput()
        
        #### Дата регистрации заявления
        self.fields[u'date'].widget = forms.HiddenInput()
        
        self.fields[u'phone'].widget = PhoneInputHTML5()
        
        #### Категории, услуги и документы
        self.fields[u'categories'].widget = forms.MultipleHiddenInput()
        self.fields[u'services'].widget = forms.MultipleHiddenInput()
        self.fields[u'documents'].widget = forms.MultipleHiddenInput()

    def set_new_instance_number(self):
        self.instance.number = self.__get_free_number()
        #Новый номер, значит, дату тоже надо обновить.
        self.instance.date = datetime.date.today()
        
    def clean_number(self):
        number = self.cleaned_data['number']
        
        # Редактируется текущее. Либо оставляем старый номер, либо
        if self.instance and self.instance.number is not None:
            
            if number == -1: #Оставляем старый номер
                number = self.instance.number
            # Проверка на возможность присвоения другого номера заявлению
            elif number != self.instance.number:
                st_after = Statement.objects.filter(number__gt=self.instance.number).count()
                if st_after:
                    raise forms.ValidationError('Нельзя изменить номер заявления. Существуют заявления с бо`льшим номером')
                                              
                st = Statement.objects.filter(date__gte=datetime.date(datetime.date.today().year, 1, 1)).filter(number__lt=self.instance.number).order_by('-number').values('number')
                if st and st[0]['number'] >= number:
                    raise forms.ValidationError('Номер должен быть больше %i. Укажите -1 для автоматического присвоения.'%st[0]['number'])
                
        # Создается новое заявление. Присваиваем новый уникальный номер
        elif number == -1:
            
            return self.__get_free_number()
        # Если номер указан вручную, проверяем его уникальность.
        else:
            st = Statement.objects.filter(date__gte=datetime.date(datetime.date.today().year, 1, 1)).filter(number__gte=number).order_by('-number').values('number')
            if st:
                raise forms.ValidationError('Номер должен быть больше %i. Либо укажите -1 для автоматического присвоения.'%st[0]['number'])
        
        
        return number
    '''
        Выбирает последнюю запись из БД (по номеру) за текущий год
        и увеличивает номер из записи на 1, возвращает полученное значение.
        Иначе нумерация начинается с начала (за текущий год не было еще ни одной записи)
    '''   
    def __get_free_number(self):
        number = 1
        try:
            
            st = Statement.objects.filter(date__gte=datetime.date(datetime.date.today().year, 1, 1)).order_by('-number').values('number')
            if st:
                number = st[0]['number'] + 1
        except IndexError:
            pass
        except Exception:
            pass
        
        return number

    def clean_phone(self):
        from util import clean_phone
        
        phone = self.cleaned_data['phone']
        
        if ',' in phone:
            new_phone = ', '.join([clean_phone(x.strip()) for x in phone.split(',')])
        else:
            new_phone = clean_phone(phone)
        
        #if not new_phone:
        #    raise forms.ValidationError(u'Телефон указан неверно')
        
        return new_phone

class DocumentCountForm(forms.Form):
    pass


class SearchForm(forms.Form):
    
    last_name = forms.CharField(max_length=25, label=u'Фамилия')
    first_name = forms.CharField(max_length=25, required=False, label=u'Имя')
    patronymic = forms.CharField(max_length=25, required=False, label=u'Отчество')
    
    
    